﻿using Furion.FriendlyException;

namespace Logics;

/// <summary>
/// 金币
/// </summary>
public class Glod : ISingleton
{
    private readonly ISqlSugarClient db;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="db"></param>
    public Glod(ISqlSugarClient db)
    {
        this.db = db;
    }

    /// <summary>
    /// 设置积分并记录日志
    /// </summary>
    /// <returns></returns>
    public async Task<bool> SetAndLog(int usedType, int storeId, int userId, dynamic glod, string memo)
    {
        var glodInfo = await db.Queryable<Entity.ClientGlod>().FirstAsync(x => x.ClientId == userId && x.StoreId == storeId);

        if (glodInfo == null)
        {
            glodInfo = new Entity.ClientGlod
            {
                ClientId = userId,

                Glod = 0,

                StoreId = storeId,
            };

            glodInfo.Id = await db.Insertable(glodInfo).ExecuteReturnIdentityAsync();
        }

        if (usedType == 0)
        {
            if (glodInfo.Glod < glod) throw Oops.Oh("金币不足");

            glodInfo.Glod -= glod;
        }
        else
        {
            glodInfo.Glod += glod;
        }

        try
        {
            db.Ado.BeginTran();

            var log = new Entity.ClientGlodLog
            {
                After = glodInfo.Glod,

                Glod = glod,

                ClientId = userId,

                UsedType = usedType,

                StoreId = storeId,

                Memo = memo
            };

            await db.Insertable(log).ExecuteCommandAsync();

            await db.Updateable(glodInfo).ExecuteCommandAsync();

            db.Ado.CommitTran();

            return true;
        }
        catch (Exception)
        {
            db.Ado.RollbackTran();

            return false;
        }
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="storeId"></param>
    /// <param name="glod"></param>
    /// <param name="memo"></param>
    /// <returns></returns>
    public async Task<bool> Add(int userId, int storeId, dynamic glod, string memo)
    {
        return await SetAndLog(1, storeId, userId, glod, memo);
    }

    /// <summary>
    /// 扣除
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="storeId"></param>
    /// <param name="glod"></param>
    /// <param name="memo"></param>
    /// <returns></returns>
    public async Task<bool> Deduct(int userId, int storeId, dynamic glod, string memo)
    {
        return await SetAndLog(0, storeId, userId, glod, memo);
    }
}
